package design.proxy;

import java.lang.reflect.Proxy;

/**
 * 代理测试【动态代理】
 * 【模式】
 * 对于代理模式，其实就是把通过三方接口去调用实现类，而不直接去调用实现类
 *
 * @author wei.yang on 2018/8/8
 */
@SuppressWarnings("unused")
public class ProxyTest {

    public static void main(String[] args) {
        System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
        proxyByJdk();
        proxyByCglib();
    }

    /**
     * jdk自带方法
     * 【不同点】
     * 没有接口，这里不给代理；
     * 代理类与委托类实现同一接口，主要是通过代理类实现InvocationHandler并重写invoke方法来进行动态代理的，
     * 在invoke方法中将对方法进行增强处理
     */
    private static void proxyByJdk() {
        Behavior behavior = (Behavior) Proxy.newProxyInstance(ProxyHandler.class.getClassLoader(), new Class[]{Behavior.class},
                new ProxyHandler(new BehaviorImpl()));
        behavior.behavior();
    }

    /**
     * cglib实现代理
     * 【不同点】
     * cglib并不要求要代理的对象有接口，只要有实现类就行；不能对final类以及final方法进行代理;
     * 【实现方式】
     * 代理类将委托类作为自己的父类并为其中的非final委托方法创建两个方法，一个是与委托方法签名相同的方法，它在方法中会通过super
     * 调用委托方法；另一个是代理类独有的方法。在代理方法中，它会判断是否存在实现了MethodInterceptor接口的对象，若存在则将调用
     * intercept方法对委托方法进行代理
     */
    private static void proxyByCglib() {
        Behavior behavior = (Behavior) new BehaviorInterceptor(new BehaviorImpl()).toInstant();
        behavior.behavior();
    }
}
